package com.hydra.cron.client.work;

import com.google.common.collect.Maps;
import com.hydra.cron.common.constants.C;
import com.hydra.cron.common.curator.helper.CuratorHelper;
import com.hydra.cron.common.utils.ObjectUtil;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * hdyraCron Created by ZhengGong on 15/12/22.
 * PackageName com.hydra.cron.client.work
 * Description
 */
public class WorkManager {
    private static final String TOKEN = UUID.randomUUID().toString().replace("-", "");
    private static final Logger LOG = LoggerFactory.getLogger(WorkManager.class);

    private Map<String, StatusListener> statusListenerMap = Maps.newConcurrentMap();

    private Map<String, IWork> workMap = Maps.newConcurrentMap();
    private String serverName;

    private AtomicBoolean isStart = new AtomicBoolean(false);

    public WorkManager(String serverName) {
        this.serverName = serverName;
    }

    public void add(IWork work) {
        workMap.put(work.workName(), work);
    }

    public synchronized void start() throws Exception {
        if (!isStart.get()) {
            statusListenerMap.put(C.JOB_STATUS.RUN, new StatusListener() {

                public void statusChange(String jobKey) {
                    IWork work = workMap.get(jobKey);

                    work.doWork();

                    while (!work.isFinish()) {
                        work.doWork();
                    }

                    try {
                        CuratorHelper.getInstance().update(workPathBuild(serverName, jobKey, TOKEN), C.JOB_STATUS.FINISH);
                    } catch (Exception e) {
                        LOG.error("update error", e);
                    }
                }
            });

            // 创建数据临时节点
            CuratorHelper.getInstance().createEphemeral(clientPathBuild(serverName, TOKEN), "0");

            // 注册功能临时节点
            if (ObjectUtil.isNotEmpty(workMap)) {
                for (final String key : workMap.keySet()) {
                    final String workNodePath = workPathBuild(serverName, key, TOKEN);


                    CuratorHelper.getInstance().createEphemeral(workNodePath, C.JOB_STATUS.CLOSE);
                    CuratorHelper.getInstance().watch(workNodePath, new NodeCacheListener() {
                        public void nodeChanged() throws Exception {
                            String status = CuratorHelper.getInstance().getData(workNodePath);

                            StatusListener statusListener = statusListenerMap.get(status);
                            if (ObjectUtil.isNotNull(statusListener)) {
                                statusListener.statusChange(key);
                            }
                        }
                    });
                }
            }
        } else {
            throw new RuntimeException("WorkManager is started");
        }
    }

    public interface StatusListener {
        void statusChange(String jobKey);
    }

    private String clientPathBuild(String serverName, String token) {
        return C.PATH.CLIENT_PATH + "/" + serverName + "/" + token;
    }

    private String workPathBuild(String serverName, String jobKey, String token) {
        return C.PATH.WORK_PATH + "/" + serverName + "/" + jobKey + "/" + token;
    }

    static {

    }
}
